//
// Created by twetec on 25-8-16.
//

#include "../include/network_prober/probe_detect/handle_http_probe_detect.h"

#include <boost/json.hpp>
#include <base64/base64.h>
#include <zlib.h>
#include <iconv.h>
#include <brotli/decode.h>
#include <httplib.h>
#include <boost/algorithm/string.hpp>
#include <boost/url.hpp>

#include <network_prober/utils/constants.h>

using namespace std::literals::chrono_literals;

namespace network_prober::probe_detect
{
std::ostream& operator<<(std::ostream& out, const HTTPProbeDetectResultIPv4& result)
{
    out
        << "interface: " << result.interface
        << " & uuid: " << result.target
        << " & delay: " << result.delay;

    return out;
}

// static std::string s_decompressBr(const std::string& compressed) {
//     size_t available_in = compressed.size();
//     const uint8_t* next_in = reinterpret_cast<const uint8_t*>(compressed.data());
//
//     // 初始输出缓冲区大小
//     size_t available_out = compressed.size() * 4;
//     std::vector<uint8_t> outbuf(available_out);
//
//     BrotliDecoderState* state = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
//     if (!state) {
//         throw std::runtime_error("Failed to create Brotli decoder instance");
//     }
//
//     size_t total_out = 0;
//     BrotliDecoderResult result;
//
//     do {
//         uint8_t* next_out = outbuf.data() + total_out;
//         available_out = outbuf.size() - total_out;
//
//         result = BrotliDecoderDecompressStream(
//             state,
//             &available_in,
//             &next_in,
//             &available_out,
//             &next_out,
//             &total_out
//         );
//
//         if (result == BROTLI_DECODER_RESULT_ERROR) {
//             BrotliDecoderErrorCode error = BrotliDecoderGetErrorCode(state);
//             BrotliDecoderDestroyInstance(state);
//             throw std::runtime_error("Brotli decompression failed with error: " +
//                                    std::to_string(error));
//         }
//
//         // 如果输出缓冲区不足，扩大它
//         if (available_out == 0) {
//             outbuf.resize(outbuf.size() * 2);
//         }
//     } while (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
//
//     BrotliDecoderDestroyInstance(state);
//
//     return std::string(reinterpret_cast<const char*>(outbuf.data()), total_out);
// }

// static std::string s_decompressDeflate(const std::string& compressed, int windowBits = -15 /* 负数表示原始deflate */) {
//     z_stream zs;
//     memset(&zs, 0, sizeof(zs));
//
//     if (inflateInit2(&zs, windowBits) != Z_OK) {
//         throw std::runtime_error("inflateInit2 failed");
//     }
//
//     zs.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(compressed.data()));
//     zs.avail_in = compressed.size();
//
//     int ret;
//     std::vector<char> outbuffer(32768); // 初始32KB缓冲区
//     std::string out;
//
//     do {
//         zs.next_out = reinterpret_cast<Bytef*>(outbuffer.data());
//         zs.avail_out = outbuffer.size();
//
//         ret = inflate(&zs, 0);
//
//         if (out.size() < zs.total_out) {
//             out.append(outbuffer.data(), zs.total_out - out.size());
//         }
//
//         if (ret != Z_OK && ret != Z_STREAM_END) {
//             inflateEnd(&zs);
//             throw std::runtime_error("inflate failed: " + std::string(zs.msg ? zs.msg : ""));
//         }
//     } while (ret == Z_OK);
//
//     inflateEnd(&zs);
//
//     // 处理没有正确报告数据长度的情况
//     if (zs.total_out > out.size()) {
//         out = out + std::string(outbuffer.data(), zs.total_out - out.size());
//     }
//
//     return out;
// }

// static std::string s_decompressGzip(const std::string& compressed) {
//     z_stream zs;
//     memset(&zs, 0, sizeof(zs));
//
//     // 使用 gzip 头部检测
//     if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK) {
//         throw std::runtime_error("inflateInit2 failed");
//     }
//
//     zs.next_in = (Bytef*)compressed.data();
//     zs.avail_in = compressed.size();
//
//     int ret;
//     char outbuffer[32768];
//     std::string outstring;
//
//     // 获取解压后的数据
//     do {
//         zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
//         zs.avail_out = sizeof(outbuffer);
//
//         ret = inflate(&zs, 0);
//
//         if (outstring.size() < zs.total_out) {
//             outstring.append(outbuffer, zs.total_out - outstring.size());
//         }
//     } while (ret == Z_OK);
//
//     inflateEnd(&zs);
//
//     if (ret != Z_STREAM_END) {
//         std::ostringstream oss;
//         oss << "Error during decompression (" << ret << ")";
//         throw std::runtime_error(oss.str());
//     }
//
//     return outstring;
// }

// static std::string s_GBKToUTF8(const std::string& gbk_str)
// {
//     iconv_t cd = iconv_open("UTF-8", "GBK");
//     if(cd == (iconv_t)-1) return gbk_str;
//
//     size_t in_len = gbk_str.size();
//     size_t out_len = in_len * 4;
//     char* in_buf = const_cast<char*>(gbk_str.data());
//     std::string utf8_str(out_len, '\0');
//     char* out_buf = &utf8_str[0];
//
//     if(iconv(cd, &in_buf, &in_len, &out_buf, &out_len) == (size_t)-1)
//     {
//         iconv_close(cd);
//         return gbk_str;
//     }
//
//     iconv_close(cd);
//     utf8_str.resize(utf8_str.size() - out_len);
//     return utf8_str;
// }

void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, HTTPProbeDetectResultIPv4 const &c)
{
    auto& ja = jv.emplace_object();

    ja["interface"] = c.interface;
    ja["target"] = c.target;
    ja["port"] = c.port;
    ja["delay"] = c.delay;
}

HandleHTTPProbeDetectIPv4::HandleHTTPProbeDetectIPv4(
    std::string_view interface,
    std::string_view target,
    std::string_view responseCode,
    bool ignoreTsl,
    std::string_view requestMethod, //  目标端口
    std::string_view requestHeader,  // 地址类型 ipv4/ipv6
    std::string_view requestBody,
    bool responseChallenge,
    std::string_view userName,
    std::string_view password,
    bool matchCondition,
    std::string_view keyWords
)
    : m_interface(interface), m_target(target), m_responseCode(responseCode), m_ignoreTsl(ignoreTsl),
    m_requestMethod(requestMethod), m_requestHeader(requestHeader), m_requestBody(requestBody),
    m_responseChallenge(responseChallenge), m_userName(userName), m_password(password), m_matchCondition(matchCondition), m_keyWords(keyWords)
{
}

void HandleHTTPProbeDetectIPv4::setOnDetectedCallback(std::function<void(HTTPProbeDetectResultIPv4 &&)> callback)
{
    m_onDetectedCallback = std::move(callback);
}

void HandleHTTPProbeDetectIPv4::detect()
{
    // 指向当前对象的shared_ptr
    auto self{shared_from_this()};

    // 发起探测
    m_detectFuture = std::async(std::launch::async, [this, self]() {
        // 构建探测结果
        HTTPProbeDetectResultIPv4 result {
            .interface = m_interface,
            .target = m_target,
            .delay = -1
        };

        // 从目标地址中解析出需要的部分
        boost::urls::url url{m_target};

        // 获取目标主机相关地址
        std::stringstream ss;
        ss << url.scheme() << "://" << url.host();
        // 判断是否有端口号，有的话就拼接
        if (!url.port().empty()) {
            ss << ":" << url.port();
        }
        SPDLOG_INFO("HTTP-IPv4协议目标 - 主机地址：{}", ss.str());

        // 构建请求
        httplib::Client client(ss.str());

        // 设置超时时间(s)
        client.set_max_timeout(8 * 1000);
        // 绑定网口
        client.set_interface(m_interface);

        // 请求和响应都正常时的日志回调
        client.set_logger([&](const httplib::Request& req, const httplib::Response& resp) {
            SPDLOG_INFO("HTTP-IPv4通信正常: {} -> {} :: {} <- {}", m_interface, req.method, ss.str(), resp.body);
        });
        // 请求和响应有不正常时的日志回调
        client.set_error_logger([&](const httplib::Error& err, const httplib::Request* req) {
            SPDLOG_INFO("HTTP-IPv4通信异常： {} -> {} :: {} <- {}", m_interface, req->method, ss.str(), httplib::to_string(err));
        });

        // 创建请求头
        httplib::Headers requestHeader {
            {"Accept", R"(text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7)"},
            {"Accept-Encoding", R"(gzip, deflate, br)"},
            {"Content-Type", R"(text/plain; charset=utf-8)"},
            {"User-Agent", R"(Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36)"}
        };
        // 解析并设置请求头 Accept: application/json\nAccept-Language: zh-CN,zh;q=0.9\nAuthorization: Bearer nV0kDIT7nPHczQ9soXfbThWdDTsCANdXBBfRJiPAdfs\nConnection: keep-alive\nReferer: http://172.16.3.115/\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
        if (!m_requestHeader.empty()) {
            // 字符串位置
            std::size_t searchStart = 0;
            std::size_t searchEnd = m_requestHeader.find("\n", searchStart);

            // 1、将整个header用\n分割为单独的条目
            std::vector<std::string> headerItems;
            headerItems.reserve(10);
            while (searchEnd != std::string::npos) {
                // 找到一个\n时，截取
                headerItems.push_back(m_requestHeader.substr(searchStart, searchEnd - searchStart));
                // 将start指向剩余的字符串
                searchStart = searchEnd + 1;
                // 从新的start位置再次查找
                searchEnd = m_requestHeader.find("\n", searchStart);
            }
            // 最后一段
            headerItems.push_back(m_requestHeader.substr(searchStart));

            // 2、将单独的条目用: 分割为key->value对
            for (auto it = headerItems.begin(); it != headerItems.end(); ++it) {
                // 重置位置
                searchStart = 0;
                searchEnd = it->find(": ", searchStart);

                std::string itemKey;
                while (searchEnd != std::string::npos) {
                    itemKey = it->substr(searchStart, searchEnd - searchStart);
                    searchStart = searchEnd + 2;
                    searchEnd = it->find(": ", searchStart);
                }
                // 3、设置进请求头中
                requestHeader.emplace(itemKey, it->substr(searchStart));
            }
        }

        // 身份校验(如果需要校验身份)
        if (m_responseChallenge) {
            client.set_basic_auth(m_userName, m_password);
        }

        // 请求开始时间
        std::chrono::time_point<std::chrono::steady_clock> detectStartTime = std::chrono::steady_clock::now();
        // 发送请求,返回请求结果
        httplib::Result reqResult;

        // 根据请求方式发起请求
        if (m_requestMethod == "1") {   // GET
            // 拼地址
            std::stringstream ss;
            ss << url.path();   // /v1/obs/page
            if (!url.query().empty()) {
                ss << "?" << url.encoded_query();   // /v1/obs/page?pageNum=1&pageSize=100
            }
            SPDLOG_INFO("HTTP-IPv4协议GET目标 - 资源地址：{}", ss.str());
            reqResult = client.Get(ss.str(), requestHeader);
        }
        else if (m_requestMethod == "2") {  // POST
            SPDLOG_INFO("HTTP-IPv4协议POST目标 - 资源地址：{}", url.path());
            reqResult = client.Put(url.path(), requestHeader, m_requestBody, "");
        }
        else if (m_requestMethod == "3") {  // PUT
            SPDLOG_INFO("HTTP-IPv4协议PUT目标 - 资源地址：{}", url.path());
            reqResult = client.Put(url.path(), requestHeader, m_requestBody, "");
        }
        else if (m_requestMethod == "4") {  // DELETE
            SPDLOG_INFO("HTTP-IPv4协议DELETE目标 - 资源地址：{}", url.path());
            reqResult = client.Delete(url.path(), requestHeader, m_requestBody, "");
        }
        else if (m_requestMethod == "5") {  // HEAD
            // 拼地址
            std::stringstream ss;
            ss << url.path();   // /v1/obs/page
            if (!url.query().empty()) {
                ss << "?" << url.encoded_query();   // /v1/obs/page?pageNum=1&pageSize=100
            }
            SPDLOG_INFO("HTTP-IPv4协议HEAD目标 - 资源地址：{}", ss.str());
            reqResult = client.Head(ss.str(), requestHeader);
        }
        else if (m_requestMethod == "6") {  // OPTIONS
            // 拼地址
            std::stringstream ss;
            ss << url.path();   // /v1/obs/page
            if (!url.query().empty()) {
                ss << "?" << url.query();   // /v1/obs/page?pageNum=1&pageSize=100
            }
            SPDLOG_INFO("HTTP-IPv4协议OPTIONS目标 - 资源地址：{}", ss.str());
            reqResult = client.Options(ss.str(), requestHeader);
        }
        else if (m_requestMethod == "7") {  // PATCH
            SPDLOG_INFO("HTTP-IPv4协议PATCH目标 - 资源地址：{}", url.path());
            reqResult = client.Delete(url.path(), requestHeader, m_requestBody, "");
        }

        // 根据通信结果，作相应处理 (只关注要设置延迟的分支) 如果目标端可达，则如果响应码不是按照要求返回的，则计算延迟
        if (reqResult && std::to_string(reqResult->status).starts_with(m_responseCode)) {    // 如果reqResult为false，表示目标端不可达，则不作任何处理
            // 如果响应码正确，并且是以2开头，表示有内容返回，需要查看是否有匹配关键字
            if (std::to_string(reqResult->status).starts_with("2") && !m_keyWords.empty()) {
                // 获取页面内容
                bool isKeywordMatched = false;    // 关键字是否匹配
                // 关键字集合
                std::istringstream iss{m_keyWords};
                // 获取关键字
                std::string keyword;
                while (std::getline(iss, keyword, ',')) {
                    // 如果内容中存在关键字
                    if (reqResult->body.find(keyword) != std::string::npos) {
                        isKeywordMatched = true;
                        break;
                    }
                }

                // 如果条件相同，表示关键字的匹配和设置匹配的需要相对应，则计算延迟
                if (m_matchCondition == isKeywordMatched) {
                    result.delay = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - detectStartTime).count();
                }
            }
            // 如果响应码正确，但不是以2开头，表示没有内容返回，直接计算延迟
            else {
                result.delay = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - detectStartTime).count();
            }
        }

        // 日志输出
        // 回调, 返回探测结果
        m_onDetectedCallback(std::move(result));
    });
}

HandleHTTPProbeDetectIPv4::~HandleHTTPProbeDetectIPv4()
{

}

std::ostream& operator<<(std::ostream& out, const HTTPProbeDetectResultIPv6& result)
{
    out
        << "interface: " << result.interface
        << " & uuid: " << result.target
        << " & delay: " << result.delay;

    return out;
}

void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, HTTPProbeDetectResultIPv6 const &c)
{
    auto& ja = jv.emplace_object();

    ja["interface"] = c.interface;
    ja["target"] = c.target;
    ja["port"] = c.port;
    ja["delay"] = c.delay;
}

HandleHTTPProbeDetectIPv6::HandleHTTPProbeDetectIPv6(
    std::string_view interface,
    std::string_view target,
    std::string_view responseCode,
    bool ignoreTsl,
    std::string_view requestMethod, //  目标端口
    std::string_view requestHeader,  // 地址类型 ipv4/ipv6
    std::string_view requestBody,
    bool responseChallenge,
    std::string_view userName,
    std::string_view password,
    bool matchCondition,
    std::string_view keyWords
)
    : m_interface(interface), m_target(target), m_responseCode(responseCode), m_ignoreTsl(ignoreTsl),
    m_requestMethod(requestMethod), m_requestHeader(requestHeader), m_requestBody(requestBody),
    m_responseChallenge(responseChallenge), m_userName(userName), m_password(password), m_matchCondition(matchCondition), m_keyWords(keyWords)
{
}

void HandleHTTPProbeDetectIPv6::setOnDetectedCallback(std::function<void(HTTPProbeDetectResultIPv6 &&)> callback)
{
    m_onDetectedCallback = std::move(callback);
}

void HandleHTTPProbeDetectIPv6::detect()
{
    // 指向当前对象的shared_ptr
    auto self{shared_from_this()};

    // 发起探测
    m_detectFuture = std::async(std::launch::async, [this, self]() {
        // 构建探测结果
        HTTPProbeDetectResultIPv6 result {
            .interface = m_interface,
            .target = m_target,
            .delay = -1
        };

        // 从目标地址中解析出需要的部分
        boost::urls::url url{m_target};

        // 获取目标主机相关地址
        std::stringstream ss;
        ss << url.scheme() << "://" << url.host();
        // 判断是否有端口号，有的话就拼接
        if (!url.port().empty()) {
            ss << ":" << url.port();
        }
        SPDLOG_INFO("HTTP-IPv6协议目标 - 主机地址：{}", ss.str());

        // 构建请求
        httplib::Client client(ss.str());

        // 设置超时时间(s)
        client.set_max_timeout(8 * 1000);
        // 绑定网口
        client.set_interface(m_interface);

        // 请求和响应都正常时的日志回调
        client.set_logger([&](const httplib::Request& req, const httplib::Response& resp) {
            SPDLOG_INFO("HTTP-IPv6通信正常: {} -> {} :: {} <- {}", m_interface, req.method, ss.str(), resp.body);
        });
        // 请求和响应有不正常时的日志回调
        client.set_error_logger([&](const httplib::Error& err, const httplib::Request* req) {
            SPDLOG_INFO("HTTP-IPv6通信异常： {} -> {} :: {} <- {}", m_interface, req->method, ss.str(), httplib::to_string(err));
        });

        // 创建请求头
        httplib::Headers requestHeader {
            {"Accept", R"(text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7)"},
            {"Accept-Encoding", R"(gzip, deflate, br)"},
            {"Content-Type", R"(text/plain; charset=utf-8)"},
            {"User-Agent", R"(Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36)"}
        };
        // 解析并设置请求头 Accept: application/json\nAccept-Language: zh-CN,zh;q=0.9\nAuthorization: Bearer nV0kDIT7nPHczQ9soXfbThWdDTsCANdXBBfRJiPAdfs\nConnection: keep-alive\nReferer: http://172.16.3.115/\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
        if (!m_requestHeader.empty()) {
            // 字符串位置
            std::size_t searchStart = 0;
            std::size_t searchEnd = m_requestHeader.find("\n", searchStart);

            // 1、将整个header用\n分割为单独的条目
            std::vector<std::string> headerItems;
            headerItems.reserve(10);
            while (searchEnd != std::string::npos) {
                // 找到一个\n时，截取
                headerItems.push_back(m_requestHeader.substr(searchStart, searchEnd - searchStart));
                // 将start指向剩余的字符串
                searchStart = searchEnd + 1;
                // 从新的start位置再次查找
                searchEnd = m_requestHeader.find("\n", searchStart);
            }
            // 最后一段
            headerItems.push_back(m_requestHeader.substr(searchStart));

            // 2、将单独的条目用: 分割为key->value对
            for (auto it = headerItems.begin(); it != headerItems.end(); ++it) {
                // 重置位置
                searchStart = 0;
                searchEnd = it->find(": ", searchStart);

                std::string itemKey;
                while (searchEnd != std::string::npos) {
                    itemKey = it->substr(searchStart, searchEnd - searchStart);
                    searchStart = searchEnd + 2;
                    searchEnd = it->find(": ", searchStart);
                }
                // 3、设置进请求头中
                requestHeader.emplace(itemKey, it->substr(searchStart));
            }
        }

        // 身份校验(如果需要校验身份)
        if (m_responseChallenge) {
            client.set_basic_auth(m_userName, m_password);
        }

        // 请求开始时间
        std::chrono::time_point<std::chrono::steady_clock> detectStartTime = std::chrono::steady_clock::now();
        // 发送请求,返回请求结果
        httplib::Result reqResult;

        // 根据请求方式发起请求
        if (m_requestMethod == "1") {   // GET
            // 拼地址
            std::stringstream ss;
            ss << url.path();   // /v1/obs/page
            if (!url.query().empty()) {
                ss << "?" << url.encoded_query();   // /v1/obs/page?pageNum=1&pageSize=100
            }
            SPDLOG_INFO("HTTP-IPv6协议GET目标 - 资源地址：{}", ss.str());
            reqResult = client.Get(ss.str(), requestHeader);
        }
        else if (m_requestMethod == "2") {  // POST
            SPDLOG_INFO("HTTP-IPv6协议POST目标 - 资源地址：{}", url.path());
            reqResult = client.Put(url.path(), requestHeader, m_requestBody, "");
        }
        else if (m_requestMethod == "3") {  // PUT
            SPDLOG_INFO("HTTP-IPv6协议PUT目标 - 资源地址：{}", url.path());
            reqResult = client.Put(url.path(), requestHeader, m_requestBody, "");
        }
        else if (m_requestMethod == "4") {  // DELETE
            SPDLOG_INFO("HTTP-IPv6协议DELETE目标 - 资源地址：{}", url.path());
            reqResult = client.Delete(url.path(), requestHeader, m_requestBody, "");
        }
        else if (m_requestMethod == "5") {  // HEAD
            // 拼地址
            std::stringstream ss;
            ss << url.path();   // /v1/obs/page
            if (!url.query().empty()) {
                ss << "?" << url.encoded_query();   // /v1/obs/page?pageNum=1&pageSize=100
            }
            SPDLOG_INFO("HTTP-IPv6协议HEAD目标 - 资源地址：{}", ss.str());
            reqResult = client.Head(ss.str(), requestHeader);
        }
        else if (m_requestMethod == "6") {  // OPTIONS
            // 拼地址
            std::stringstream ss;
            ss << url.path();   // /v1/obs/page
            if (!url.query().empty()) {
                ss << "?" << url.encoded_query();   // /v1/obs/page?pageNum=1&pageSize=100
            }
            SPDLOG_INFO("HTTP-IPv6协议OPTIONS目标 - 资源地址：{}", ss.str());
            reqResult = client.Options(ss.str(), requestHeader);
        }
        else if (m_requestMethod == "7") {  // PATCH
            SPDLOG_INFO("HTTP-IPv6协议PATCH目标 - 资源地址：{}", url.path());
            reqResult = client.Delete(url.path(), requestHeader, m_requestBody, "");
        }

        // 根据通信结果，作相应处理 (只关注要设置延迟的分支) 如果目标端可达，则如果响应码不是按照要求返回的，则计算延迟
        if (reqResult && std::to_string(reqResult->status).starts_with(m_responseCode)) {    // 如果reqResult为false，表示目标端不可达，则不作任何处理
            // 如果响应码正确，并且是以2开头，表示有内容返回，需要查看是否有匹配关键字
            if (std::to_string(reqResult->status).starts_with("2") && !m_keyWords.empty()) {
                // 获取页面内容
                bool isKeywordMatched = false;    // 关键字是否匹配
                // 关键字集合
                std::istringstream iss{m_keyWords};
                // 获取关键字
                std::string keyword;
                while (std::getline(iss, keyword, ',')) {
                    // 如果内容中存在关键字
                    if (reqResult->body.find(keyword) != std::string::npos) {
                        isKeywordMatched = true;
                        break;
                    }
                }

                // 如果条件相同，表示关键字的匹配和设置匹配的需要相对应，则计算延迟
                if (m_matchCondition == isKeywordMatched) {
                    result.delay = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - detectStartTime).count();
                }
            }
            // 如果响应码正确，但不是以2开头，表示没有内容返回，直接计算延迟
            else {
                result.delay = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - detectStartTime).count();
            }
        }

        // 日志输出
        // 回调, 返回探测结果
        m_onDetectedCallback(std::move(result));
    });
}

HandleHTTPProbeDetectIPv6::~HandleHTTPProbeDetectIPv6()
{

}

}